// 定义自定义校验约束类
import {
  ValidatorConstraint, // 用于定义自定义校验约束
  ValidatorConstraintInterface, // 自定义校验约束需要实现的接口
  ValidationArguments, // 校验时的参数，包含属性名、值、约束等信息
  registerDecorator, // 用于注册自定义装饰器
  ValidationOptions, // 校验选项，例如错误消息
} from 'class-validator';
import { InjectRepository } from '@nestjs/typeorm';
import { UserEntity } from '../entities/user.entity';
import { Repository } from 'typeorm';

@ValidatorConstraint({ name: 'StartsWith', async: false }) // 装饰器，标记这是一个校验约束类
export class StartWithConstraint implements ValidatorConstraintInterface {
  // 默认错误消息
  // 当校验失败时，会调用该方法生成错误消息
  // validationArguments 包含校验时的上下文信息，例如属性名、值、约束等
  defaultMessage(validationArguments?: ValidationArguments): string {
    if (validationArguments.constraints) {
      // 从 constraints 中获取前缀
      const [prefix] = validationArguments.constraints;
      // 返回自定义的错误消息
      return `${validationArguments.property} must start with ${prefix}`;
    } else {
      return validationArguments.property + '必须以user_开头';
    }
  }

  // 校验逻辑
  // value 是当前属性的值
  // validationArguments 包含校验时的上下文信息
  validate(value: any, validationArguments?: ValidationArguments): boolean {
    // 校验值是否以指定前缀开头
    return value.startsWith('user_');
  }
}

// 定义自定义装饰器函数
// prefix: 前缀，用于校验字符串是否以该前缀开头
// validationOptions: 校验选项，例如自定义错误消息
export function StartsWith(
  prefix: string,
  validationOptions?: ValidationOptions,
) {
  // 返回一个装饰器函数
  return function (object: Object, propertyName: string) {
    // 注册自定义装饰器
    registerDecorator({
      name: 'StartsWith', // 装饰器的名称
      target: object.constructor, // 目标类（DTO 类）
      propertyName: propertyName, // 目标属性名
      options: validationOptions, // 校验选项
      constraints: [prefix], // 传递给校验器的参数（这里是前缀）
      validator: StartWithConstraint, // 使用的校验约束类
    });
  };
}

// // 非Controller类 注入依赖 去请求数据库
// let repositoryStartWithConstraintSync = null;
// 定义自定义校验约束类 异步的
@ValidatorConstraint({ name: 'StartsWithSync', async: true }) // 装饰器，标记这是一个校验约束类
export class StartWithConstraintSync implements ValidatorConstraintInterface {
  constructor(
    // @InjectRepository(UserEntity) protected repository: Repository<UserEntity>,
    @InjectRepository(UserEntity) protected repository: Repository<UserEntity>,
  ) {}
  defaultMessage(validationArguments?: ValidationArguments): string {
    return validationArguments.value + '该用户已存在';
  }
  validate = async (
    value: any,
    validationArguments?: ValidationArguments,
  ): Promise<boolean> => {
    // const result = await repositoryStartWithConstraintSync.findOneBy({
    const result = await this.repository.findOneBy({
      username: value,
    });
    return !result;
  };
}

// 定义自定义装饰器函数
// prefix: 前缀，用于校验字符串是否以该前缀开头
// validationOptions: 校验选项，例如自定义错误消息
export function StartsWithSync(
  prefix: string,
  validationOptions?: ValidationOptions,
) {
  // 返回一个装饰器函数
  return function (object: Object, propertyName: string) {
    // 注册自定义装饰器
    registerDecorator({
      name: 'StartsWith', // 装饰器的名称
      target: object.constructor, // 目标类（DTO 类）
      propertyName: propertyName, // 目标属性名
      options: validationOptions, // 校验选项
      constraints: [prefix], // 传递给校验器的参数（这里是前缀）
      validator: StartWithConstraintSync, // 使用的校验约束类
    });
  };
}
